﻿#ifndef PROCESS_H
#define PROCESS_H
#define MEMORY_SIZE 8192//8GB   需要是PAGE_SIZE的整数倍
#define PAGE_SIZE 8//2MB
#define Out_time 60//time_out time
#include<process.h>
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#include<vector>
using namespace std;


struct PAGETABLE{//每个进程都有一个指向这个页表
    int num_page;//该进程共几页（大小除以页大小）
    vector<vector<int>> page_entry;//程序内存分页，每一页安排到内存页  ， {程序页—内存页}

    PAGETABLE(int x):num_page(x/PAGE_SIZE){//构造函数   x为所需内存大小
    }
};


struct SEGETABLE{//每个进程都有一个指向这个段表
    int num_sege;//该进程共几段（微信红包算法随机分配）
    vector<vector<int>> sege_entry;//程序内存分段，每一段安排到内存段  ， {程序段-段长-内存段}

    SEGETABLE(int x){//构造函数   x为所需内存大小
        srand((unsigned)time(NULL));
        num_sege = rand() % 4 + 3; //随机分为3 4 5 6段
        for(int i = 0; i < num_sege; ++i){//为每一段随机长度  微信红包算法
            float temp_aver = (float)x/num_sege; //剩余平均长度
            if(i != num_sege-1){
                int temp_length = rand() % (int)(temp_aver*2) + 1;// 长度随机  [1，剩余平均两倍]
                sege_entry.push_back( {i, temp_length } );
                x -= temp_length;
            }
            else{//最后一段
                sege_entry.push_back( {i, x } );//剩余的长度都给
            }
        }
    }
};

//------------------------------------------PCB------------
struct PPCB{
    int id;             //进程的编号
    int cputime;        //进程的总CPU占用时间
    int lefttime;       //进程剩余的CPU占用时间
    int state;          //进程的状态，在哪一个队列中 1代表在运行队列 2代表在等待队列 3代表在ready队列 4代表阻塞状态
    int priority;       //进程的优先级
    PPCB *pre;          //指向进程对象的在队列中的前一个进程
    PPCB *next;         //指向进程对象在队列中的后一个进程
    PAGETABLE*  pagetable;  //该进程的页表
    SEGETABLE*  segetable;  //该进程的段表
    int memory;
    int file_id;
    int time_count;
};


//------------------------------------------CLASS------------
class process{
public:

    process(){
        processinit();
    }//构造函数

//------------------------------------------process_options------------
int timeslip;               //时间片
int scheduling_mode=1;      //当前选用的调度方式 1：轮转调度算法 2.先来先服务加优先级 3.先来先服务
//------------------------------------------------------
int run_count=0;//运行进程数量
int wait_count=0;//等待进程数量
int ready_count=0;//就绪进程数量
int block_count=0;//阻塞进程数量
int finish_count=0;//完成进程数量
int run_max=3;//最多同时三个运行中进程
int processid=1;  //用于给进程ID赋值
PPCB *runhead;   //运行队列的表头和表尾 及初始化
PPCB *runrear;
PPCB *waithead;   //等待队列的表头和表尾  及初始化
PPCB *waitrear;
PPCB *readyhead;   //就绪队列的表头和表尾  及初始化
PPCB *readyrear;
PPCB *blockhead;   //阻塞队列的表头和表尾  及初始化
PPCB *blockrear;
PPCB *finishhead;   //完成队列的表头和表尾  及初始化
PPCB *finishrear;
void  processinit();                        //在构造时初始化process
PPCB* Find_pro_byId(int id);                //根据id找到进程
PPCB* Find_pro_byfileId(int fileid);        //根据id找到进程
PPCB* Delete_process_byId(int id,int state);//根据id将进程从队列中删除,并返回该进程；
void Time_out();                            //超时处理
void Insert_run(PPCB *p);                   //将进程插入到运行队列中；
void Insert_wait(PPCB *p);                  //将进程插入到等待队列中；
void Insert_ready(PPCB *p);                 //将进程插入到就绪队列中；
void Insert_block(PPCB *p);                 //将进程加入到阻塞队列中；
void Insert_finish(PPCB *p);                //将进程插入到完成队列中；
void block_process(int id);                 //阻塞进程
void wakeup_process(int id);                //唤醒进程
PPCB* Find_next_fcfs_priority();  //FCFS_and_Priority调度时用来找到要调度的进程
PPCB* New_process(int Cuptime,int priority,int mem,int file_id);    //新建进程，参数填0表示随机生成
//调度算法
void R_r();
void Fcfs();
void Fcfs_Priority();



void Swap_process(PPCB *p,PPCB *q);  //用于交换两个进程的位置，======并没有使用到
void Show_process();//调试用，打印进程



};



#endif // PROCESS_H

